#include<stdio.h>
#include<map>
#include<algorithm>
#include<vector>
#include<math.h>
using namespace std;
int car[100009][3];
map<int,pair<int,int>> h;
vector<int> h2[29];
int a[100009];
bool f[100009];
bool f2[100009];
bool f3[100009];
int n,m,ans = 100009;
void dfs(int step=1,int t=0){
    for(int i = 1;i<=n;i++) if(f2[i]) printf(" %d!%d ",i,f[i]);
    printf("\n");
    if(step>n){
        bool flag = 1;
        if(flag) ans = min(ans,t),printf("%d %d\n",step,t);
    }
    else{
        for(int i = 1;i<=n;i++) f3[i] = f[i];
        dfs(step+1,t);
        for(auto it:h2[step]) f[it] |= 1,printf("%d ",it);
        printf("\n");
        dfs(step+1,t+1);
        for(int i = 1;i<=n;i++) f[i] = f3[i];
    }
}
int main(){
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    int t;
    scanf("%d",&t);
    while(t--){
        int l,v;
        scanf("%d %d %d %d",&n,&m,&l,&v);
        for(int i = 1;i<=n;i++){
            scanf("%d %d %d",&car[i][0],&car[i][1],&car[i][2]);
        }
        for(int i = 1;i<=m;i++){
            scanf("%d",&a[i]);
        }
        for(int i = 1;i<=n;i++){
            if(car[i][0]>a[m]) continue;
            if(car[i][2]>=0&&car[i][1]>v){
                int stt = upper_bound(a+1,a+m+1,car[i][0])-a-1;
                if(a[stt]!=car[i][0]) stt++;
                // printf("%d %d\n",a[stt],a[m]);
                h[i]=make_pair(stt,m);
            }
            else if(car[i][2]>0&&car[i][1]<=v){
                int dist = car[i][0] + (int)ceil(1.0f*(v*v-car[i][1]*car[i][1])/(2*car[i][2]));
                bool real = (double)ceil(1.0f*(v*v-car[i][1]*car[i][1])/(2*car[i][2])) == 1.0f*(v*v-car[i][1]*car[i][1])/(2*car[i][2]);
                if(dist<a[m]||(dist==a[m]&&(!real))){
                    int stt = lower_bound(a+1,a+m+1,dist)-a;
                    // printf("%d %d\n",a[stt+real],a[m]);
                    h[i]=make_pair(stt+real,m);
                }
            }
            else if(car[i][2]<0&&car[i][1]>v){
                int dist = car[i][0] + int(1.0f*(v*v-car[i][1]*car[i][1])/(2*car[i][2]));  
                bool real = (double)int(1.0f*(v*v-car[i][1]*car[i][1])/(2*car[i][2])) == 1.0f*(v*v-car[i][1]*car[i][1])/(2*car[i][2]);
                int stt = upper_bound(a+1,a+m+1,car[i][0])-a-1;
                if(a[stt]!=car[i][0]) stt++;
                if(ceil(sqrt(car[i][1]*car[i][1]-2*car[i][2]*a[stt]))<=v) continue; 
                if(dist<a[stt]) continue;
                if(dist>a[m]||(dist==a[m]&&real)) h[i]=make_pair(stt,m);
                else{
                    int ent = lower_bound(a+1,a+m+1,dist)-a;
                    // printf("%d %d\n",a[stt],a[ent-real]);
                    h[i]=make_pair(stt,ent);
                }
            }
        }
        printf("%ld ",h.size());
        // if(m<=20&&n<=20){
        //     for(auto it:h){
        //         f2[it.first] = 1;
        //         int pos1 = lower_bound(a+1,a+n+1,it.second.first)-a;
        //         int pos2 = lower_bound(a+1,a+n+1,it.second.second)-a;
        //         for(int i = pos1;i<=pos2;i++){
        //             h2[i].push_back(it.first);
        //         }
        //     }
        //     dfs();
        //     printf("%d\n",ans);
        // }
        // else 
        printf("%d\n",m-(h.size()?1:0));
        ans = 100009;
        h.clear();
    }
}